package com.lplb.common.redis.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 分布式架构获取唯一号（基于redis）--》 订单号，交易号，退款号等，如果redis 集群,需设置自增歩长,使用命令设置
 *
 * @author ws
 * @mail 1720696548@qq.com
 * @date 2020/2/20 0020 15:02
 */
@Configuration
public class RedisNoUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
//    @Autowired
//    private RedisUtil redisUtil;

    /**
     * 获取唯一Id（20位）
     *
     * @param key   key前缀--  实际key等于前缀+每秒时间戳(同一秒delta 自增，下一秒根据时间戳生成新的key,delta重新计算)
     * @param delta 默认初始自增值
     *              *** 2019-10-20 12:00:01 000001 --> 20191020120001000001,20191020120001000002,20191020120001000003......
     *              *** 2019-10-20 12:00:02 000001 --> 20191020120002000001,20191020120002000002,20191020120002000003......
     * @return java.lang.String
     * @author ws
     * @mail 1720696548@qq.com
     * @date 2020/2/20 0020 15:59
     */
    public String getNo(String key, Long delta) {
        try {
            // delta为空默认值1
            if (null == delta) {
                delta = 1L;
            }
            // 生成14位的时间戳(每秒使用新的时间戳当key)
            String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            // 获得redis-key
            String newKey = key + ":" + timeStamp;
            // 获取自增值（时间戳+自定义key）
            Long increment = redisTemplate.opsForValue().increment(newKey, delta);
            // 设置时间戳生成的订单号为有效期为1秒,使1秒内不会生成重复的key
            redisTemplate.expire(newKey, 1, TimeUnit.SECONDS);
            // 获取订单号，时间戳 + 唯一自增Id( 6位数,不过前方补0)
            String orderOn = timeStamp + String.format("%06d", increment);
            // 设置订单超时时间(30 * 60L = 30分钟) -- 测试60秒,当key过期自动执行回调方法
            //redisTemplate.opsForValue().set(ORDER_TIME_KEY + orderOn, 0, 60L, TimeUnit.SECONDS);
            //redisTemplate.opsForValue().set(ORDER_TIME_KEY + orderOn, 0, 30 * 60L, TimeUnit.SECONDS);
            return orderOn;
        } catch (Exception e) {
            // redis 宕机时采用时间戳加随机数
            String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            Random random = new Random();
            //14位时间戳到 + 6位随机数
            timeStamp += (random.nextInt(10) + "") + (random.nextInt(10) + "") + (random.nextInt(10) + "");
            timeStamp += (random.nextInt(10) + "") + (random.nextInt(10) + "") + (random.nextInt(10) + "");
            return timeStamp;
        }
    }
}
